using System;

namespace Autofac.Integration.Prism
{
	public static class ContainerExtensions
	{
		/// <summary>
		///  Creates a child container which inherits from a parent container.
		/// </summary>
		/// <param name="container">The parent <see cref="IContainer"/>.</param>
		/// <param name="configurationAction">Optional delegate which receives a <see cref="ContainerBuilder"/> 
		/// to configure the created <see cref="IChildContainer"/>.</param>
		/// <returns>A <see cref="IChildContainer"/> instance.</returns>
		public static IChildContainer CreateChildContainer(this IContainer container, Action<ContainerBuilder> configurationAction = null)
		{
			return ChildContainer.Create(container, configurationAction);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="container">The <see cref="IContainer"/> to configure.</param>
		/// <param name="configurationAction">Delegate which receives a <see cref="ContainerBuilder"/> to setup 
		/// the configuration to apply to the <see cref="IContainer"/>.</param>
		/// <returns>The <see cref="IContainer"/>.</returns>
		public static IContainer Configure(this IContainer container, Action<ContainerBuilder> configurationAction)
		{
			if (container == null) throw new ArgumentNullException("container");
			if (configurationAction == null) throw new ArgumentNullException("configurationAction");
			
			ContainerBuilder containerBuilder = new ContainerBuilder();
			configurationAction(containerBuilder);
			containerBuilder.Update(container);

			return container;
		}


		// These are a some methods to make moving from Unity to Autofac easier for my sample app.
		// Should these be removed and inlined??
		public static IContainer RegisterInstance<T>(this IContainer container, T instance) where T: class 
		{
			if (container == null) throw new ArgumentNullException("container");

			return container.Configure(b => b.RegisterInstance(instance).As<T>());
		}

		public static T RegisterSingleton<T>(this IContainer container) where T: class
		{
			if (container == null) throw new ArgumentNullException("container");

			return container.Configure(b => b.RegisterType<T>().SingleInstance()).Resolve<T>();
		}

		public static IContainer AddService<TFrom, TTo>(this IContainer container, bool registerAsSingleton = true) where TTo: TFrom
		{
			if (container == null) throw new ArgumentNullException("container");
			
			ContainerBuilder containerBuilder = new ContainerBuilder();
			var registration = containerBuilder.RegisterType<TTo>().As<TFrom>();
			if (registerAsSingleton)
			{
				registration = registration.SingleInstance();
			}
			containerBuilder.Update(container);

			return container;
		}

	}
}